import 'dart:convert';
import 'dart:typed_data';

import 'package:ble_helper_plugin/library.dart';
import 'package:bluetooth_protocols_parser_plugin/library.dart';
import 'package:inmotion_pro/config/const.dart';
import 'package:inmotion_pro/pages/mixin/vehicle_type_mixin.dart';
import 'package:inmotion_pro/pages/models/realtime_item.dart';
import 'package:inmotion_pro/pages/models/user_model.dart';
import 'package:inmotion_pro/pages/models/vehicle_model.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_battery_info.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_realtime_all_info.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_realtime_error.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_realtime_info.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_realtime_status.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_settings.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_statistics_once.dart';
import 'package:inmotion_pro/service/realtime_data_server/vehicle_realtime_data/vehicle_statistics_total.dart';
import 'package:inmotion_pro/service/app_lifecycle_service.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';

// 全局服务
// 主要用于存储一些全局状态，本地缓存等
// 这些状态不属于某个特定的页面或模块
// 例如：
// 1. 用户登录状态
// 2. 是否是游客模式
// 3. 本地缓存是否存在可用车辆
class GlobalService extends GetxService with VehicleTypeMixin {
  // 全局服务
  static GlobalService get to => Get.find();

  // 底部导航栏Tab 红点数字
  final RxList<int> badgeCounts = [0, 0, 0].obs;

  // 底部导航栏Tab 是否显示小红点
  final RxList<bool> showBadges = [false, false, false].obs;

  // 检查应用是否在前台
  bool get isForeground =>
      Get.find<AppLifecycleService>().isAppInForeground.value;

  // 是否是游客模式
  bool get isGuest => cacheUserInfo.value.uid == guestUid;

  // 是否登录
  bool get isLoggedIn => cacheUserInfo.value.token.isNotEmpty;

  // 是否中国地区
  RxBool isChinaRegion = false.obs;

  // 区号
  RxString phoneCode = ''.obs;

  // 缓存的用户信息
  Rx<UserModel> cacheUserInfo = UserModel.fromMap({}).obs;

  // 缓存的车辆列表
  RxList<VehicleModel> cacheVehicleList = <VehicleModel>[].obs;

  // 当前车辆
  Rx<VehicleModel> currentVehicleModel = VehicleModel.fromJson({}).obs;

  // 缓存的实时信息列表项
  RxList<RealtimeItemModel> cacheRealtimeItems = <RealtimeItemModel>[].obs;

  // 所有实时信息
  Rx<VehicleRealtimeAllInfo> realtimeAllInfo =
      VehicleRealtimeAllInfo.fromMap({}).obs;

  // 实时信息
  Rx<VehicleRealtimeInfo> realtimeInfo = VehicleRealtimeInfo.fromMap({}).obs;

  // 实时状态
  Rx<VehicleRealtimeStatus> realtimeStatus =
      VehicleRealtimeStatus.fromMap({}).obs;

  // 实时错误
  Rx<VehicleRealtimeError> realtimeError = VehicleRealtimeError.fromMap({}).obs;

  // 实时电池信息
  Rx<VehicleBatteryInfo> realtimeBattery = VehicleBatteryInfo.fromMap({}).obs;

  // 实时统计一次数据
  Rx<VehicleStatisticsOnce> realtimeStatisticsOnce =
      VehicleStatisticsOnce.fromMap({}).obs;

  // 实时统计总数据
  Rx<VehicleStatisticsTotal> realtimeStatisticsTotal =
      VehicleStatisticsTotal.fromMap({}).obs;

  // 实时设置
  Rx<VehicleSettings> realtimeSetting = VehicleSettings.fromMap({}).obs;

  // 全局升级标识，部分业务（后台任务：上传骑行记录）需要以此为依据做出调整
  // 例如：如果在升级过程中，则禁止上传车辆骑行数据等
  bool isUpgrading = false;

  // 获取用户标识符
  Uint8List get identifierBytes =>
      Uint8List.fromList(utf8.encode("${cacheUserInfo.value.uid}"));

  // httpHeaders for AdvancedNetworkImage
  Map<String, String> get httpHeaders {
    String token = cacheUserInfo.value.token;
    Map<String, String> httpHeaders = {};
    httpHeaders['Authorization'] = 'Bearer $token';
    return httpHeaders;
  }

  // 根据当前车辆模型获取车辆类型
  VehicleType get currentVehicleType => vehicleTypeMixinGetVehicleType(
      bleName: currentVehicleModel.value.bleName);

  // 判断人机版版本号，来决定是否需要使用综合产品信息或者综合实时信息 V9人机板1.8.50  V12S 1.8.68  P6
  bool get isIntegratedInfoAvailable {
    try {
      // 检查人机版版本号是否支持综合信息
      bool hasCompatibleHmi = currentVehicleModel.value.firmwareInfoList.any(
        (item) =>
            item.deviceId == TargetDeviceType.eucHmic.rawValue &&
            vehicleTypeMixinIsSupportIntegratedInfo(
              item.appVersion,
              bleName: currentVehicleModel.value.bleName,
            ),
      );
      return hasCompatibleHmi;
    } catch (e) {
      return false;
    }
  }

  // 判断人机版版本号，来决定是否需要支持实时信息主动上报能力
  bool isSupportRealtimePush([CustomScanResult? scanResult]) {
    try {
      // 检查人机版版本号是否支持综合信息
      bool hasCompatibleHmi =
          currentVehicleModel.value.firmwareInfoList.any((item) =>
              item.deviceId == TargetDeviceType.eucHmic.rawValue &&
              vehicleTypeMixinIsSupportRealtimePush(
                item.appVersion,
                bleName: currentVehicleModel.value.bleName,
              ));
      // 如果提供了扫描结果的设备，验证设备是否与当前车辆匹配
      if (scanResult != null) {
        return hasCompatibleHmi &&
            currentVehicleModel.value.bleName == scanResult.device.advName;
      }
      return hasCompatibleHmi;
    } catch (e) {
      return false;
    }
  }

  // 【监听属性】，当前用户的地区域
  // Root中会将缓存中的区域赋值给它，以便全局使用
  // AreaHelper中如果用户修改了区域信息，也会更新它
  RxString currentUserArea = ''.obs;

  // 【监听属性】，当前显示的车辆BleName变化
  RxString currentVehicleBleName = ''.obs;

  // 【监听属性】，当前显示的车辆车主变化
  RxnBool isCurrentVehicleOwner = RxnBool();
}

// 全局服务扩展方法
extension GlobalServiceExtension on GlobalService {
  // 清空当前用户相关的全局状态
  void clearCurrentUserGlobalState() {
    cacheUserInfo.value = UserModel.fromMap({});
    currentUserArea.value = '';
    clearCurrentVehicleGlobalState();
  }

  // 清空当前车辆相关的全局状态
  void clearCurrentVehicleGlobalState() {
    cacheVehicleList.clear();
    currentVehicleModel.value = VehicleModel.fromJson({});
    cacheRealtimeItems.value = <RealtimeItemModel>[];
    currentVehicleBleName.value = '';
    isCurrentVehicleOwner.value = null;
    realtimeAllInfo.value = VehicleRealtimeAllInfo.fromMap({});
    realtimeInfo.value = VehicleRealtimeInfo.fromMap({});
    realtimeStatus.value = VehicleRealtimeStatus.fromMap({});
    realtimeError.value = VehicleRealtimeError.fromMap({});
    realtimeBattery.value = VehicleBatteryInfo.fromMap({});
    realtimeStatisticsOnce.value = VehicleStatisticsOnce.fromMap({});
    realtimeStatisticsTotal.value = VehicleStatisticsTotal.fromMap({});
    realtimeSetting.value = VehicleSettings.fromMap({});
  }
}
